﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//  ITimeSpanFormatter.cs
//    
// Abstract:
//
//   Interface describing a class intended for formatting DateTimes for printing
//   in reminders.
//--

using System;
using System.Globalization;

namespace Microsoft.EnhancedReminders.Dispatcher
{
    /// <summary>
    /// Interface describing a class intended for formatting DateTimes for printing
    /// in reminders.
    /// </summary>
	public interface ITimeSpanFormatter
	{
        /// <summary>
        /// Adds friendly text for a time span for an overdue appointment or meeting. This typically
        /// has a form similar to "you have a meeting that started at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        string OverdueTimeSpan(CultureInfo cultureInfo, DateTime startTime);

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts in less than an hour.
        /// This typically has a form similar to "you have a meeting in 20 minutes."
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="span">A TimeSpan representing the lead time to the meeting or appointment</param>
        string ImmediateTimeSpan(CultureInfo cultureInfo, TimeSpan span);

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime today, but later
        /// than an hour. This typically has a form similar to "you have a meeting at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        string TimeSpanToday(CultureInfo cultureInfo, DateTime startTime);

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime tomorrow.
        /// This typically has a form similar to "you have a meeting tomorrow at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        string TimeSpanTomorrow(CultureInfo cultureInfo, DateTime startTime);

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime later than tomorrow.
        /// This typically has a form similar to "you have a meeting on Monday, October 12 at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the time span in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        string DistantTimeSpan(CultureInfo cultureInfo, DateTime startTime);
	}

    /// <summary>
    /// ITimespanFormatter implementation for printing time spans for Instant Message Reminders. This
    /// class is also intended to be a base class for other ITimeSpanFormatters that may only need
    /// to override a handful of the timespan strings that this class generates.
    /// </summary>
    public class InstantMessageTimeSpanFormatter : ITimeSpanFormatter
    {
        #region ITimespanFormatter Members

        /// <summary>
        /// Adds friendly text for a time span for an overdue appointment or meeting. This typically
        /// has a form similar to "you have a meeting that started at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public virtual string OverdueTimeSpan(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Present, startTime.ToString("h:mm tt", cultureInfo));
        }

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts in less than an hour.
        /// This typically has a form similar to "you have a meeting in 20 minutes."
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="span">A TimeSpan representing the lead time to the meeting or appointment</param>
        public virtual string ImmediateTimeSpan(CultureInfo cultureInfo, TimeSpan span)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Future, 
                string.Format(cultureInfo, Math.Abs(span.Minutes) == 1 ? 
                    IMResources.Minutes_Singular : 
                    IMResources.Minutes_Plural, Math.Abs(span.Minutes)));
        }

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime today, but later
        /// than an hour. This typically has a form similar to "you have a meeting at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public virtual string TimeSpanToday(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Today, startTime.ToString("h:mm tt", cultureInfo));
        }

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime tomorrow.
        /// This typically has a form similar to "you have a meeting tomorrow at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public virtual string TimeSpanTomorrow(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Tomorrow, startTime.ToShortTimeString());
        }

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime later than tomorrow.
        /// This typically has a form similar to "you have a meeting on Monday, October 12 at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public virtual string DistantTimeSpan(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Distant,
                startTime.ToString("dddd, MMMM dd", cultureInfo),
                startTime.ToString("h:mm tt", cultureInfo));
        }

        #endregion
    }

    /// <summary>
    /// ITimespanFormatter implementation for printing time spans for Voice Reminders that
    /// are delivered via TTS.
    /// </summary>
    public class SsmlTimeSpanFormatter : InstantMessageTimeSpanFormatter
    {
        #region ITimeSpanFormatter Members

        /// <summary>
        /// Adds friendly text for a time span for an overdue appointment or meeting. This typically
        /// has a form similar to "you have a meeting that started at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public override string OverdueTimeSpan(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Present,
                string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                    startTime.ToString("hh:mm", cultureInfo), startTime.ToString("tt", cultureInfo)));
        }

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime today, but later
        /// than an hour. This typically has a form similar to "you have a meeting at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public override string TimeSpanToday(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Today,
                string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                startTime.ToString("hh:mm", cultureInfo), startTime.ToString("tt", cultureInfo)));
        }

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime tomorrow.
        /// This typically has a form similar to "you have a meeting tomorrow at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public override string TimeSpanTomorrow(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Tomorrow,
                string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                startTime.ToString("hh:mm", cultureInfo), startTime.ToString("tt", cultureInfo)));
        }

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime later than tomorrow.
        /// This typically has a form similar to "you have a meeting on Monday, October 12 at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public override string DistantTimeSpan(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Distant,
                string.Format(CultureInfo.InvariantCulture, "{1} <say-as type=\"date:md\">{0}</say-as>", 
                    startTime.ToString("MM-dd", cultureInfo), startTime.ToString("dddd", cultureInfo)),
                string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                    startTime.ToString("hh:mm", cultureInfo), startTime.ToString("tt", cultureInfo)));
        }

        #endregion
    }

    /// <summary>
    /// ITimespanFormatter implementation for printing time spans for SMS Reminders
    /// </summary>
    public class SmsTimeSpanFormatter : InstantMessageTimeSpanFormatter
    {
        #region ITimeSpanFormatter Members

        /// <summary>
        /// Adds friendly text for a time span for an appointment or meeting that starts sometime later than tomorrow.
        /// This typically has a form similar to "you have a meeting on Monday, October 12 at 12:00 PM"
        /// </summary>
        /// <param name="cultureInfo">The culture to print the timespan in</param>
        /// <param name="startTime">The time the meeting/appointment occurs at</param>
        public override string DistantTimeSpan(CultureInfo cultureInfo, DateTime startTime)
        {
            return string.Format(cultureInfo, IMResources.LeadTime_Distant,
                startTime.ToString("ddd, MMM dd", cultureInfo),
                startTime.ToString("h:mm tt", cultureInfo));
        }

        #endregion
    }
}
